/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package assignment3;

import java.util.Arrays;
import java.util.Random;

/**
 *
 * @author Christopher
 */
public class Chromosome {
    int [] m_chromosome;
    int m_geneCount;
    
    Chromosome(int geneCount)
    {
        m_geneCount = geneCount;
        m_chromosome = new int[geneCount];
        Arrays.fill(m_chromosome,-1);
    }
    
    Chromosome(int[] genes)
    {
        m_geneCount = genes.length;
        m_chromosome = genes;
    }
    
    public void generate()
    {
        Random random = new Random();
        int numGenes=0;
        while(numGenes<m_geneCount)
        {
            int gene = random.nextInt(m_geneCount);
            if(!contains(m_chromosome,gene))
            {
                m_chromosome[numGenes] = gene;
                numGenes++;
            }
        }
    }
    
    public int[] mutate()
    {
        Random random = new Random();
        int[] newChromosome = m_chromosome;
        int fromIndex = random.nextInt(m_geneCount);
        int toIndex = random.nextInt(m_geneCount);
        while(fromIndex == toIndex)
        {
            toIndex = random.nextInt(m_geneCount);
        }
        int temp = newChromosome[fromIndex];
        newChromosome[fromIndex] = newChromosome[toIndex];
        newChromosome[toIndex] = temp;
        return newChromosome;
    }
    
    public int[] crossover(Chromosome chromosome)
    {
        int[] child = new int[m_geneCount];
        Arrays.fill(child,-1);
        Random random = new Random();
        int startIndex = random.nextInt(m_geneCount);
        int endIndex = random.nextInt(m_geneCount);
        while(startIndex == endIndex)
        {
            endIndex = random.nextInt(m_geneCount);
        }
        if(startIndex > endIndex)
        {
            int temp;
            temp = startIndex;
            startIndex = endIndex;
            endIndex = temp;
        }
        System.arraycopy(this.m_chromosome, startIndex, child, startIndex, (endIndex - startIndex)+1);
        int numGenes = endIndex-(startIndex-1);
        int currentGene = 0;
        int testGene = 0;
        for(int i=0;i<m_geneCount;i++)
        {
            insert(chromosome.at(i),child);
        }
        
        return child;
    }
    
    void insert(int newNumber, int[] source)
    {
        if(contains(source,newNumber))
        {
            return;
        }
        else
        {
            int i=0;
            boolean placed = false;
            while(i<m_geneCount && !placed)
            {
                if(source[i] == -1)
                {
                    source[i] = newNumber;
                    placed = true;
                }
                i++;
            }
        }
    }
    
    boolean contains(int[] input,int match)
    {
        for(int i=0; i<input.length; i++)
        {
            if(input[i] == match)
            {
                return true;
            }
        }
        return false;
    }
    
    public int at(int index)
    {
        return m_chromosome[index];
    }
    
    @Override
    public String toString()
    {
        return Arrays.toString(m_chromosome);
    }

    public double calculateDistance() 
    {
        double distance = 0.0;
        for(int i=1; i<m_geneCount; i++)
        {
            distance += Math.pow((m_chromosome[i-1] - m_chromosome[i]),2)+2*(Math.sqrt(m_chromosome[i-1] * m_chromosome[i]));
        }
        distance += Math.pow((m_chromosome[m_geneCount-1] - m_chromosome[0]),2)+2*(Math.sqrt(m_chromosome[m_geneCount-1] * m_chromosome[0]));
        return distance;
    }
}
